import { useUserStore } from '@/store'

export default class ChatHandler {
    sqlite: any
    userInfo: any
    constructor(sqlite: any) {
        this.sqlite = sqlite
        this.userInfo = useUserStore().userInfo
    }

    /**
     * 获取最新聊天记录，默认拉取服务器最新记录，若少于10条，本地拉取10条
     */
    newList(otherId: string | number) {
        // 查询本地用户列表
        return new Promise((resolve, reject) => {
            uni.$u.$api.ImChat.newList(otherId).then((frecords: Array<any>) => {
                if (frecords && frecords.length > 0) {
                    this.sqlite.imChat.save(frecords).then((records: Array<any>) => {
                        if (records.length < 10) {
                            this.historyList(otherId, uni.$u.$timeUtil.formatDate(records[0].createTime)).then((hrecords: any) => {
                                if (hrecords && hrecords.length > 0) {
                                    records.unshift(...hrecords)
                                }
                                resolve(records)
                            })
                        } else {
                            resolve(records)
                        }
                    })
                } else {
                    this.historyList(otherId, uni.$u.$timeUtil.formatDate(new Date())).then(records => {
                        resolve(records)
                    })
                }
            })
        })
    }

    /**
     * 优先拉取本地数据，没有则拉取服务器数据
     * @param otherId
     * @param firstTime
     */
    historyList(otherId: any, firstTime: any) {
        let user = this.userInfo
        return new Promise((resolve, reject) => {
            // 屏蔽当前五分钟前的所以发送失败的图片，文件，语音
            let dt = new Date()
            dt.setMinutes(dt.getMinutes() - 5)
            let dtStr = uni.$u.$timeUtil.formatDate(dt)
            let failStr = `and (( type in (2, 3, 4) and id = 0 and create_time > '${dtStr}') or (id != 0))`
            this.sqlite.imChat
                .getList({
                    where: `where ((sender = ${otherId} and receiver = ${user.userId}) or (sender = ${user.userId} and receiver = ${otherId}))
                    and create_time < '${firstTime}' ${failStr} order by create_time desc, kid desc limit 10`
                })
                .then((brecords: any) => {
                    if (brecords && brecords.length > 0) {
                        resolve(brecords.sort((a: any, b: any) => (a.createTime > b.createTime ? 1 : -1)))
                    } else {
                        uni.$u.$api.ImChat.historyList(otherId, firstTime).then((frecords: any) => {
                            if (frecords && frecords.length > 0) {
                                this.sqlite.imChat.save(frecords).then((records: any) => {
                                    resolve(records)
                                })
                            } else {
                                resolve(frecords)
                            }
                        })
                    }
                })
        })
    }

    /**
     * 发送消息，优先本地存储，后发送至服务器
     * @param list
     * @returns {*}
     */
    send({ receiver, content, success, process, error }: { receiver: any; content: any; success: Function; process: Function; error: Function }) {
        // 判断content是否为数组
        if (Array.isArray(content)) {
            content.forEach(it => {
                if (typeof it === 'string') {
                    it = JSON.parse(content)
                }
            })
        } else if (typeof content === 'string') {
            content = [JSON.parse(content)]
        } else {
            content = [content]
        }
        // 封装chat
        let user = this.userInfo
        let chatList: Array<any> = []
        content.forEach((it: any) => {
            chatList.push({
                type: this.dealTypeForNum(it.type),
                receiver,
                sender: user.userId,
                content: JSON.stringify(it),
                contentObj: it,
                createTime: uni.$u.$timeUtil.formatDate(new Date()),
                updateTime: uni.$u.$timeUtil.formatDate(new Date())
            })
        })
        this.sqlite.imChat
            .save(chatList)
            .then((bChat: any) => {
                if (bChat) {
                    // 因为 发送多张图片时  需要按照选择图片的顺序 发送 因此 这里的上传顺序 也需要有序进行
                    // 将 chat 对象 的 循环上传 易容到 下边 使用reduce  进行 有序 执行
                    bChat.reduce(async (PromiseChain: any, chat: any) => {
                        if ([1, 5].indexOf(chat.type) >= 0) {
                            // 如果是文本/卡片则直接发送
                            process(0, chat)
                            PromiseChain.then(this.sendText({ chat, success, error }))
                        } else if (chat && [2, 3, 4].indexOf(chat.type) >= 0) {
                            chat.local = chat.contentObj.url || chat.contentObj.src
                            // 判断文件是否存在
                            let b = await uni.$u.$fileUtil.existsSync(chat.local)
                            if (!b) {
                                // 回滚掉数据
                                this.sqlite.imChat.delete({ whereObj: { kid: chat.kid } })
                                return
                            }
                            process(0, chat)

                            PromiseChain.then(this.uploadFile({ chat, success, error, process, exitsFile: true }))
                        } else {
                            return Promise.resolve()
                        }
                    }, Promise.resolve())
                }
            })
            .catch(() => {
                error(0, '发送消息失败')
            })
    }

    /**
     *  重新发送
     */
    sendAgain({ chat, success, process, error }: { chat: any; success: Function; process: Function; error: Function }) {
        // 先查询是否已经上传成功
        this.sqlite.imChat.getChatByKid(chat.kid).then((d: any) => {
            // 如果已经上传成功了，则直接返回success
            if (d.id && d.delFlag === 0) {
                success(d)
            } else {
                // 如果是文本直接发送
                if (!chat.contentObj) {
                    chat.contentObj = JSON.parse(chat.content)
                }
                if ([1, 5].indexOf(chat.type) >= 0) {
                    // 如果是文本则直接发送
                    this.sendText({ chat, success, error })
                } else if ([2, 3, 4].indexOf(chat.type) >= 0) {
                    if (chat.kid) {
                        if (chat.contentObj.i) {
                            this.sendFile({ chat, success, error })
                        } else {
                            chat.local = chat.contentObj.url || chat.contentObj.src
                            this.uploadFile({ chat, success, error, process })
                        }
                    } else {
                        error(1, '无法发送，请删除重新发送', chat)
                    }
                }
            }
        })
    }

    sendText({ chat, success, error }: { chat: any; success: Function; error: Function }) {
        return new Promise(resolve => {
            // 消息内容处理
            let contentJ
            if (chat.type === 1) {
                contentJ = {
                    c: chat.contentObj.content || chat.contentObj.c
                }
            } else if (chat.type === 5) {
                if (chat.contentObj.no) {
                    contentJ = {
                        f: chat.contentObj.no,
                        t: chat.contentObj.model,
                        h: chat.contentObj.title,
                        i: chat.contentObj.picId,
                        c: chat.contentObj.price
                    }
                } else {
                    contentJ = chat.contentObj
                }
            }
            chat.contentObj = contentJ
            chat.content = JSON.stringify(contentJ)
            uni.$u.$api.ImChat.send(chat)
                .then((fchat: any) => {
                    // 更新本地
                    fchat.kid = chat.kid
                    this.sqlite.imChat.updateById(fchat)
                    // 聊天列表置顶
                    //fchat.lastContent = this.vm.$u.$imHandler.dealLastContent(fchat.type, fchat.contentObj)
                    //this.vm.$store.dispatch('addListByNewChat', {chat: fchat, isCur: false})
                    // 不传导致撤回操作双向绑定失效
                    fchat.delFlag = false
                    // 回调成功方法
                    success(fchat)
                    resolve('')
                })
                .catch((err: any) => {
                    resolve('')
                    error(2, err, chat)
                })
        })
    }

    uploadFile({ chat, success, error, process, exitsFile }: { chat: any; success: Function; error: Function; process: Function; exitsFile?: any }) {
        return new Promise(async resolve => {
            if (!exitsFile) {
                // 判断文件是否存在
                let b = await uni.$u.$fileUtil.existsSync(chat.local)
                if (!b) {
                    error(1, '文件已不存在', chat)
                    return
                }
            }
            // 上传文件
            uni.$u.$api.ImFile.imUpload({
                path: chat.local,
                type: chat.contentObj.type,
                width: chat.contentObj.w ? chat.contentObj.w : 10,
                height: chat.contentObj.h ? chat.contentObj.h : 10,
                uploadProgress: (num: number) => {
                    process(num, chat)
                }
            })
                .then((ret: any) => {
                    // 重新组装chat, 发送至服务器
                    let contentObj: any
                    if (chat.type === 2) {
                        contentObj = {
                            i: ret.id,
                            w: chat.contentObj.w,
                            h: chat.contentObj.h,
                            s: chat.contentObj.size,
                            e: chat.contentObj.typeDsc
                        }
                    } else if (chat.type === 3) {
                        contentObj = {
                            i: ret.id,
                            t: chat.contentObj.time,
                            e: chat.contentObj.name
                        }
                    } else if (chat.type === 4) {
                        contentObj = {
                            i: ret.id,
                            e: chat.contentObj.name,
                            s: chat.contentObj.size
                        }
                    }
                    // 将目标文件复制到指定目录
                    let filename = ret.id + (contentObj.e || '')
                    let ext = chat.type === 2 ? contentObj.e : null
                    let target = uni.$u.$fileUtil.dealCachePath(filename, ext)
                    uni.$u.$fileUtil.copyFileToTarget({
                        url: chat.local,
                        target,
                        success: (path: string) => {
                            console.log(path)
                            chat.local = path
                            chat.contentObj = contentObj
                            chat.content = JSON.stringify(contentObj)
                            // 同步展示数据
                            process(100, chat)
                            // 优先更新本地数据
                            this.sqlite.imChat.updateById(chat)
                            this.sendFile({ chat, success, error }).then(() => {
                                resolve('')
                            })
                        },
                        error: (err: any) => {
                            chat.local = ''
                            chat.contentObj = contentObj
                            chat.content = JSON.stringify(contentObj)
                            // 同步展示数据
                            process(100, chat)
                            // 优先更新本地数据
                            this.sqlite.imChat.updateById(chat)
                            this.sendFile({ chat, success, error })
                                .then(() => {
                                    resolve('')
                                })
                                .catch(e => {
                                    console.log(err)
                                    resolve('')
                                })
                        }
                    })
                })
                .catch((err: any) => {
                    resolve('')
                    error(1, err, chat)
                })
        })
    }

    sendFile({ chat, success, error }: { chat: any; success: Function; error: Function }) {
        return new Promise(resolve => {
            // 调用发送消息接口
            uni.$u.$api.ImChat.send(chat)
                .then((rchat: any) => {
                    // 本地更新
                    rchat.kid = chat.kid
                    rchat.local = chat.local
                    rchat.delFlag = 0
                    this.sqlite.imChat.updateById(rchat)
                    // 调用成功接口
                    success(rchat)
                    resolve('')
                })
                .catch((err: any) => {
                    resolve('')
                    error(2, err)
                })
        })
    }

    dealTypeForNum(type: string) {
        switch (type) {
            case 'text':
                return 1
            case 'image':
                return 2
            case 'voice':
                return 3
            case 'file':
                return 4
            case 'card':
                return 5
            default:
                return 4
        }
        return null
    }

    /**
     * 查询需要更新的阅读状态记录(只查自己发送的消息)
     * @returns {*}
     */
    readStatusUpdateList(otherId: any) {
        console.log('==============================================')
        // let user = this.userInfo
        // return new Promise(resolve => {
        //     this.sqlite.imChat.readStatusLastTime(user.userId, otherId).then((lastTime: any) => {
        //         if (lastTime) {
        //             .Chat.readStatusUpdateList(otherId, lastTime).then((frecords: any) => {
        //                 if (frecords && frecords.length > 0) {
        //                     resolve(frecords)
        //                     // 本地更新阅读状态
        //                     frecords.forEach(chat => {
        //                         this.sqlite.imChat.update({
        //                             data: chat,
        //                             whereObj: {
        //                                 id: chat.id
        //                             }
        //                         })
        //                     })
        //                 } else {
        //                     resolve(null)
        //                 }
        //             })
        //         } else {
        //             resolve(null)
        //         }
        //     })
        // })
    }

    addNewChat(chat: any) {
        return new Promise((resolve, reject) => {
            // 存入本地
            if (chat.lastContent != '结束服务') {
                // 处理时间
                this.sqlite.imChat.save(chat).then((record: any) => {
                    if (record && record.length > 0) {
                        resolve(record[0])
                    }
                })
            } else {
                resolve(chat)
            }
        })
    }

    deleteChat(kid: any) {
        return this.sqlite.imChat.delete({ whereObj: { kid: kid } })
    }

    cancelChat(chat: any) {
        return new Promise((resolve, reject) => {
            // 调用服务器接口
            uni.$u.$api.ImChat.cancelChat(chat.id).then((fchat: any) => {
                fchat.kid = chat.kid
                this.sqlite.imChat.updateById(fchat)
                resolve(fchat)
            })
        })
    }

    /**
     * 状态通知，更新本地并返回信息
     * @returns {*}
     */
    statusUpdate(chatArr: any) {
        return new Promise(resolve => {
            // 本地更新阅读状态
            chatArr.forEach((chat: any) => {
                this.sqlite.imChat
                    .update({
                        data: chat,
                        whereObj: {
                            id: chat.id
                        }
                    })
                    .then(() => {
                        resolve(chatArr)
                    })
            })
        })
    }

    /**
     * 获取 服务器 最新的一条消息  用于 消息中心页面 列表显示
     * @param {Number} otherId 聊天对方的ID
     */
    getlastChatMessage(otherId: any) {
        return new Promise((resolve, reject) => {
            uni.$u.$api.ImChat.getlastMessage({ otherId })
                .then((res: any) => {
                    resolve(res)
                })
                .catch(() => {
                    reject()
                })
        })
    }
}
